package cn.ztydata.teachingsystem.heaven.web.interceptor;

import cn.ztydata.teachingsystem.heaven.common.PrivilegeLoaderFactory;
import cn.ztydata.teachingsystem.heaven.cons.Roles;
import cn.ztydata.teachingsystem.heaven.entity.User;
import cn.ztydata.teachingsystem.heaven.entity.oxm.PrivilegeInfo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 权限验证拦截器
 * Created by chenxin on 2014/11/13.
 */
public class PrivilegeInterceptor extends HandlerInterceptorAdapter {
    private Logger log = LoggerFactory.getLogger(PrivilegeInterceptor.class); //日志记录器

    @Value("${session.key}")
    private String sessionKey;

    @Autowired
    private PrivilegeLoaderFactory privilegeLoaderFactory;

    /**
     * 处理前校验权限
     * @param request http请求
     * @param response http响应
     * @param handler 处理器
     * @return boolean
     * @throws Exception 异常
     *
     * @author chenxin
     * @since 2014/11/13
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        User user = (User) request.getSession().getAttribute(sessionKey);
        if (user.getRole() < 0) {
            log.debug("登录用户角色无效:user.getRole() < 0");

            log.warn("登录用户角色无效:role->" + user.getRole());
            response.setStatus(401);
            return false;
        }

        //如果登录角色为超级管理员则跳过验证继续进行
        if (Roles.SUPER_ADMIN == user.getRole()) {
            log.debug("Roles.SUPER_ADMIN == user.getRole()");

            return true;
        }

        //获取请求的uri
        String uri = request.getRequestURI();
        //忽略项目名的有无对权限的截取（针对域名映射的情况）
        String context = request.getContextPath();
        if (StringUtils.isNotEmpty(context)) {
            log.debug("url中无应用名:StringUtils.isNotEmpty(context)");

            uri = StringUtils.removeStart(uri, context);
        }

        //从url中截取权限字段
        String[] uris = StringUtils.split(uri, "/");
        String privilege = "/" + uris[0] + "/" + uris[1];

        //获取请求方式
        String method = request.getMethod();

        ServletContext servletContext = request.getSession().getServletContext();
        //加载默认权限信息
        PrivilegeInfo defaultPrivilegeInfo = privilegeLoaderFactory.load(Roles.DEFAULT, servletContext);
        //加载权限信息
        PrivilegeInfo privilegeInfo = privilegeLoaderFactory.load(user.getRole(), servletContext);

        if (defaultPrivilegeInfo == null || privilegeInfo == null) {
            log.debug("加载权限信息失败:privilegeInfo == null");

            log.warn("加载权限信息失败:defaultPrivilegeInfo->{}, privilegeInfo->{}", defaultPrivilegeInfo, privilegeInfo);
            response.setStatus(500);
            return false;
        }

        //判断用户权限是否有效
        if (defaultPrivilegeInfo.judgePrivilege(method, privilege) || privilegeInfo.judgePrivilege(method, privilege)) {
            log.debug("判断用户权限是否有效");

            //验证通过
            return true;
        }

        log.warn("权限验证失败:privilege->{},method->{}", privilege, method);
        response.setStatus(403);

        log.debug("权限验证失败");
        return false;
    }
}
